package com.xdtech.core.listener;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

import com.xdtech.common.service.impl.BaseService;
import com.xdtech.common.utils.ClassUtil;
import com.xdtech.core.config.PropertiesConfigurer;
import com.xdtech.core.init.SysInitOperation;
import com.xdtech.core.model.BaseModel;
/**
 * spring容器启动加载配置文件完成监听器
 * 
 * @author max.zheng
 * @create 2014-9-25下午9:36:10
 * @since 1.0
 * @see
 */
@SuppressWarnings("rawtypes")
@Component
public class SysInitListener implements ApplicationListener {
	@Autowired
	private BaseService<BaseModel> baseService;
	//存放系统初始化模块的class
	private Map<Integer, Class> initClasses =new HashMap<Integer, Class>();
	private Logger log = Logger.getLogger(getClass());

	public void onApplicationEvent(ApplicationEvent event) {
		String eventSource = event.getSource().toString();
		if (eventSource.startsWith("Root WebApplicationContext:")) {
//			Root WebApplicationContext: startup date [Thu Sep 25 21:17:58 CST 2014]; root of context hierarchy
			log.info("spring 主配置文件加载完毕");
			try {
				
				List<Integer> orderList = new ArrayList<Integer>();
				Object initDataEntity = null;
				Method convertMethod = null;
				Integer initOrder = null;
				//获取初始化模块
				String sysInitModules = PropertiesConfigurer.sysInitModules();
				//进行排序
				for(Class initDataClass : ClassUtil.getClasses("com.xdtech"))
				{
					if (SysInitOperation.class.isAssignableFrom(initDataClass)&&!SysInitOperation.class.equals(initDataClass)) {
						if (sysInitModules.contains(initDataClass.getSimpleName()))
						{
							initDataEntity = initDataClass.newInstance();
							convertMethod = initDataClass.getMethod(SysInitOperation.INIT_GET_ORDER);
							initOrder = (Integer) convertMethod.invoke(initDataEntity);
							initClasses.put(initOrder, initDataClass);
							orderList.add(initOrder);
						}
					}
					
				}
				//排序设置初始化顺序
				Collections.sort(orderList);
				if (PropertiesConfigurer.sysIsInitDataToDb()) {
					try {
						initSysData(SysInitOperation.INIT_TO_DB_METHOD,orderList,initClasses);
					} catch (Exception e) {
						log.error("初始化数据库数据失败",e);
					}
					PropertiesConfigurer.setAlreadyInitDataToDb();
					PropertiesConfigurer.changeAlreadyFlag("system.isInitDataToDb","false");
				}
				if (PropertiesConfigurer.sysIsInitDataToCache()) {
					try {
						initSysData(SysInitOperation.INIT_TO_CACHE_METHOD,orderList,initClasses);
					}catch (Exception e) {
						log.error("初始化缓存数据失败",e);
					}
				}
			} catch (Exception e) {
				log.error("初始化数据失败",e);
			}
			
			
		}
		else if (eventSource.startsWith("WebApplicationContext for namespace")) {
//			WebApplicationContext for namespace 'springmvc-servlet': startup date [Thu Sep 25 21:18:02 CST 2014]; parent: Root WebApplicationContext
			log.info("spring mvc 配置文件加载完毕");
		}
	}

	private void initSysData(String method,List<Integer> orderList,Map<Integer, Class> initClasses) throws Exception{
		log.info("初始化数据......"+method);
		Object initObject = null;
		Method convertMethod = null;
		for (Integer integer : orderList) {
			Class<?> c = initClasses.get(integer);
			initObject = c.newInstance();
			convertMethod = c.getMethod(method
					,BaseService.class);
			convertMethod.invoke(initObject,baseService);
		}
		log.info("初始化数据......"+method+"...结束......");
	}
	
	public void initDataToWebApplication(){
		try
		{
			Object initObject = null;
			Method convertMethod = null;
			for (Class<?> cls : initClasses.values())
			{
				initObject = cls.newInstance();
				convertMethod = cls.getMethod(SysInitOperation.INIT_TO_CACHE_APPLICATION
						,BaseService.class);
				convertMethod.invoke(initObject,baseService);
			}	
		}
		catch (Exception e)
		{
			log.error("初始化数据到WebApplication error",e);
		}
		
	}

}
